<?php
/**
 * 更新地铁表location、city_codes等字段
 */

namespace app\crontab\controller\once;

use custom\Log;
use custom\Mongo;
use custom\Redis;
use map\BaiDu;
use map\GaoDe;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Exception;

class Metro extends Command {

    protected function configure() {
        $this->setName('Metro');
    }

    protected function execute(Input $input, Output $output) {
        $this->initial();
    }

    public function initial() {
        echo "starting\n";
        $mongo = Mongo::getInstance();
        $cursor = $mongo->select('bk_metro', [], []);
        $lineNum = count($cursor);

        $id = 0;
        $siteArr = [];
        $siteNum = $num = 0;
        foreach ($cursor as $key => $value) {
            $id++;
            $value = (array)$value;
            $info = db('region')->where('name', $value['city'])->field('city_code,p_codes')->find();
            $city_codes = "{$info['p_codes']}{$info['city_code']},";
            // 存地铁线
            $lineData = [
                'city_codes' => $city_codes,
                'city'       => $value['city'],
                'pid'        => 0,
                'name'       => $value['line_name'],
                'rank'       => 1,
                'itime'      => time(),
                'lat'        => 0,
                'lng'        => 0,
                'location'   => Db::raw("POINT(0, 0)"),
            ];
            $lineId = db('metro_bk')->insertGetId($lineData);
            $siteArr = [];
            foreach ($value['site'] as $k => $vo) {
                $siteNum++;
                $map = $this->getAddressInfoByMap($vo, $value['city']);
                $siteArr[] = [
                    'city_codes' => $city_codes,
                    'city'       => $value['city'],
                    'pid'        => $lineId,
                    'name'       => $vo,
                    'rank'       => 2,
                    'itime'      => time(),
                    'lat'        => $map['lat'],
                    'lng'        => $map['lng'],
                    'location'   => Db::raw("POINT({$map['lng']}, {$map['lat']})"),
                    'metro_sort' => $k,
                ];
            }
            $a = db('metro_bk')->insertAll($siteArr);
            $num += $a;
        }
        echo "site-count:{$num}||siteNum:{$siteNum}||lineNum:{$lineNum}";
    }

    /**
     * 百度地图-获取详细信息
     * @param $address 詳細地址
     * @param $city 城市
     * @return array
     * @throws Exception
     */
    public function getAddressInfoByMap($address, $city = '') {
        $lat = $lng = $cityCodes = $cityCode = 0;
        // 通过标题信息获取经纬度
        $res1 = BaiDu::placeSearch($address, $city);
        if (!empty($res1['results'])) {
            $lat = $res1['results'][0]['location']['lat'] ?? 0;
            $lng = $res1['results'][0]['location']['lng'] ?? 0;
        }
        return [
            'lng' => $lng,
            'lat' => $lat,
        ];
    }

    /**
     * 高德地图-获取详细信息
     * @param $address
     * @param string $city
     * @return array
     * @throws Exception
     */
    public function getAddressInfoByMap1($address, $city = '') {
        $lat = $lng = $cityCodes = $cityCode = 0;
        $res = GaoDe::getByAddress($address, $city);
        if (!empty($res)) {
            $arr = explode(',', $res['geocodes'][0]['location']);
            $lng = $arr[0] ?? 0;
            $lat = $arr[1] ?? 0;
            $cityCode = $res['geocodes'][0]['adcode'] ?? 0;
        }

        // 通过经纬度获取地址信息
        if ($lat > 0 && $lng > 0) {
            $res2 = BaiDu::getByLocation($lat, $lng);
            if (!empty($res2['result'])) {
                $lng = round($res2['result']['location']['lng'] ?? $lng, 6);
                $lat = round($res2['result']['location']['lat'] ?? $lat, 6);
                $cityCode = $res2['result']['addressComponent']['adcode'] ?? 0;
                // 城市code集合
                if ($cityCode > 0) {
                    $pCodes = db('region')->where(['city_code' => $cityCode])->value('p_codes');
                    $cityCodes = !empty($pCodes) ? "{$pCodes}{$cityCode}," : ",{$cityCode},";
                }
            }
        }

        $location = "POINT('{$lng}', '{$lat}')";

        return [
            'location'   => $location,
            'city_code'  => $cityCode,
            'city_codes' => $cityCodes
        ];
    }
}